package org.example.batch;

import org.example.domain.Student;
import org.example.domain.StudentProcessed;
import org.springframework.batch.item.ItemProcessor;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.concurrent.atomic.AtomicLong;
import java.util.regex.Pattern;

/**
 * MyBatis版本的学生数据处理器
 * 
 * 将原始的Student对象转换为处理后的StudentProcessed对象
 * 
 * @author Spring Batch + MyBatis Demo
 */

public class MyBatisStudentProcessor implements ItemProcessor<Student, StudentProcessed> {
    
    // === 静态统计信息 ===
    private static final AtomicLong totalProcessed = new AtomicLong(0);
    private static final AtomicLong adultCount = new AtomicLong(0);
    private static final AtomicLong youthCount = new AtomicLong(0);
    private static final AtomicLong minorCount = new AtomicLong(0);
    private static final AtomicLong validDataCount = new AtomicLong(0);
    private static final AtomicLong invalidDataCount = new AtomicLong(0);
    private static volatile long startTime = 0;
    
    // 邮箱验证正则表达式
    private static final Pattern EMAIL_PATTERN = Pattern.compile(
        "^[A-Za-z0-9+_.-]+@([A-Za-z0-9.-]+\\.[A-Za-z]{2,})$"
    );
    
    // 当前批次号（线程安全）
    private static volatile String currentBatchNumber;
    
    @Override
    public StudentProcessed process(Student student) throws Exception {
        
        // 统计更新
        long currentTotal = totalProcessed.incrementAndGet();
        
        // 设置开始时间（第一次处理时）
        if (startTime == 0) {
            startTime = System.currentTimeMillis();
            currentBatchNumber = "MYBATIS-BATCH-" + System.currentTimeMillis();
        }
        
        // 每500条输出进度
        if (currentTotal % 500 == 0) {
            System.out.println("📊 MyBatis批处理进度: 已处理 " + currentTotal + " 条学生记录...");
        }
        
        try {
            // === 第一步：数据验证 ===
            if (!isValidStudent(student)) {
                invalidDataCount.incrementAndGet();
                return createErrorRecord(student, "数据验证失败");
            }
            
            // === 第二步：创建处理结果对象 ===
            StudentProcessed processed = new StudentProcessed();
            
            // 设置基础信息
            processed.setSourceStudentId(student.getId());
            processed.setAge(student.getAge());
            processed.setBatchNumber(currentBatchNumber);
            processed.setProcessedAt(LocalDateTime.now());
            
            // === 第三步：数据清洗和标准化 ===
            String cleanName = cleanStudentName(student.getName());
            String standardGender = standardizeGender(student.getGender());
            String validEmail = validateAndFixEmail(student.getEmail());
            
            // === 第四步：业务处理 - 年龄分类 ===
            String ageCategory = categorizeAge(student.getAge());
            String processedName = "[" + ageCategory + "]" + cleanName;
            
            // 更新年龄分类统计
            updateAgeCategoryStats(ageCategory);
            
            // === 第五步：数据质量评分 ===
            int qualityScore = calculateQualityScore(student, cleanName, standardGender, validEmail);
            
            // === 第六步：设置处理结果 ===
            processed.setProcessedName(processedName);
            processed.setAgeCategory(ageCategory);
            processed.setGender(standardGender);
            processed.setEmail(validEmail);
            processed.setIsValid(true);
            processed.setQualityScore(qualityScore);
            processed.setProcessStatus("PROCESSED");
            processed.setRemark(buildRemark(student, qualityScore));
            
            validDataCount.incrementAndGet();
            
            return processed;
            
        } catch (Exception e) {
            invalidDataCount.incrementAndGet();
            System.err.println("❌ MyBatis处理器异常: " + e.getMessage() + ", 学生ID: " + student.getId());
            
            return createErrorRecord(student, "处理异常: " + e.getMessage());
        }
    }
    
    /**
     * 数据验证
     */
    private boolean isValidStudent(Student student) {
        if (student == null) return false;
        if (student.getId() == null || student.getId() <= 0) return false;
        if (student.getName() == null || student.getName().trim().isEmpty()) return false;
        if (student.getAge() == null || student.getAge() < 0 || student.getAge() > 150) return false;
        return true;
    }
    
    /**
     * 姓名清洗
     */
    private String cleanStudentName(String name) {
        if (name == null) return "未知姓名";
        
        name = name.trim().replaceAll("\\s+", " ");
        name = name.replaceAll("[^\\u4e00-\\u9fa5a-zA-Z\\s]", "");
        
        if (name.length() > 20) {
            name = name.substring(0, 20);
        }
        
        return name.isEmpty() ? "未知姓名" : name;
    }
    
    /**
     * 性别标准化
     */
    private String standardizeGender(String gender) {
        if (gender == null) return "U";
        
        String g = gender.trim().toUpperCase();
        if ("M".equals(g) || "MALE".equals(g) || "男".equals(g)) {
            return "M";
        } else if ("F".equals(g) || "FEMALE".equals(g) || "女".equals(g)) {
            return "F";
        } else {
            return "U";
        }
    }
    
    /**
     * 邮箱验证和修复
     */
    private String validateAndFixEmail(String email) {
        if (email == null || email.trim().isEmpty()) {
            return null;
        }
        
        email = email.trim().toLowerCase();
        
        if (EMAIL_PATTERN.matcher(email).matches()) {
            return email;
        }
        
        email = email.replace(" ", "").replace("@@", "@");
        
        if (EMAIL_PATTERN.matcher(email).matches()) {
            return email;
        }
        
        return null;
    }
    
    /**
     * 年龄分类
     */
    private String categorizeAge(Integer age) {
        if (age == null) return "未知";
        
        if (age < 18) {
            return "未成年";
        } else if (age <= 25) {
            return "青年";
        } else if (age <= 35) {
            return "成年";
        } else if (age <= 60) {
            return "中年";
        } else {
            return "老年";
        }
    }
    
    /**
     * 更新年龄分类统计
     */
    private void updateAgeCategoryStats(String ageCategory) {
        switch (ageCategory) {
            case "未成年":
                minorCount.incrementAndGet();
                break;
            case "青年":
                youthCount.incrementAndGet();
                break;
            case "成年":
            case "中年":
            case "老年":
                adultCount.incrementAndGet();
                break;
        }
    }
    
    /**
     * 数据质量评分 (0-100)
     */
    private int calculateQualityScore(Student student, String cleanName, String gender, String email) {
        int score = 0;
        
        // 姓名质量 (30分)
        if (cleanName != null && !cleanName.equals("未知姓名")) {
            score += 30;
            if (cleanName.length() >= 2 && cleanName.length() <= 10) {
                score += 10;
            }
        }
        
        // 年龄质量 (25分)
        if (student.getAge() != null && student.getAge() >= 1 && student.getAge() <= 120) {
            score += 25;
        }
        
        // 性别质量 (20分)
        if ("M".equals(gender) || "F".equals(gender)) {
            score += 20;
        } else if ("U".equals(gender)) {
            score += 5;
        }
        
        // 邮箱质量 (25分)
        if (email != null) {
            score += 25;
        }
        
        return Math.max(0, Math.min(100, score));
    }
    
    /**
     * 构建备注信息
     */
    private String buildRemark(Student student, int qualityScore) {
        StringBuilder remark = new StringBuilder();
        
        remark.append("数据质量评分: ").append(qualityScore).append("分");
        
        if (qualityScore >= 90) {
            remark.append(", 优秀数据");
        } else if (qualityScore >= 70) {
            remark.append(", 良好数据");
        } else if (qualityScore >= 50) {
            remark.append(", 一般数据");
        } else {
            remark.append(", 较差数据");
        }
        
        return remark.toString();
    }
    
    /**
     * 创建错误记录
     */
    private StudentProcessed createErrorRecord(Student student, String errorMessage) {
        StudentProcessed errorRecord = new StudentProcessed();
        
        if (student != null) {
            errorRecord.setSourceStudentId(student.getId());
            errorRecord.setAge(student.getAge());
            errorRecord.setProcessedName("ERROR: " + (student.getName() != null ? student.getName() : "Unknown"));
        }
        
        errorRecord.setBatchNumber(currentBatchNumber);
        errorRecord.setProcessedAt(LocalDateTime.now());
        errorRecord.setIsValid(false);
        errorRecord.setQualityScore(0);
        errorRecord.setProcessStatus("ERROR");
        errorRecord.setRemark(errorMessage);
        
        return errorRecord;
    }
    
    // === 静态方法：统计信息管理 ===
    
    /**
     * 重置统计信息
     */
    public static void resetStatistics() {
        System.out.println("🔄 MyBatis批处理统计信息已重置");
        totalProcessed.set(0);
        adultCount.set(0);
        youthCount.set(0);
        minorCount.set(0);
        validDataCount.set(0);
        invalidDataCount.set(0);
        startTime = 0;
        currentBatchNumber = null;
    }
    
    /**
     * 打印统计信息
     */
    public static void printStatistics() {
        long endTime = System.currentTimeMillis();
        long duration = endTime - startTime;
        double processingRate = duration > 0 ? totalProcessed.get() * 1000.0 / duration : 0;
        
        System.out.println("\n" + "==================================================");
        System.out.println("🎯 MyBatis批处理统计信息");
        System.out.println("==================================================");
        System.out.println("📊 处理数据统计:");
        System.out.println("  总处理记录数: " + totalProcessed.get());
        System.out.println("  有效记录数: " + validDataCount.get());
        System.out.println("  无效记录数: " + invalidDataCount.get());
        System.out.println("  数据有效率: " + String.format("%.2f%%", 
            validDataCount.get() * 100.0 / Math.max(1, totalProcessed.get())));
        
        System.out.println("\n🏷️ 年龄分类统计:");
        System.out.println("  未成年学生: " + minorCount.get() + " 人");
        System.out.println("  青年学生: " + youthCount.get() + " 人");
        System.out.println("  成年学生: " + adultCount.get() + " 人");
        
        System.out.println("\n⚡ 性能统计:");
        System.out.println("  处理耗时: " + duration + " ms (" + (duration / 1000.0) + " 秒)");
        System.out.println("  处理速度: " + String.format("%.2f", processingRate) + " 记录/秒");
        System.out.println("  批次号: " + currentBatchNumber);
        
        System.out.println("==================================================");
    }
    
    /**
     * 获取当前批次号
     */
    public static String getCurrentBatchNumber() {
        return currentBatchNumber;
    }
}
